<?php
defined('OA_LIB_PATH') || define('OA_LIB_PATH', '/opt/op/OALib');
defined('OPEN_LIB_PATH') || define('OPEN_LIB_PATH', '/opt/op/OpenLib');

require_once 'OaLogic.php';
require_once OA_LIB_PATH . '/inner/service/OAApi.php';
require_once OA_LIB_PATH . '/inner/service/OASApi.php';
require_once OPEN_LIB_PATH . '/open/models/OaAppModel.php';
require_once OPEN_LIB_PATH . '/open/models/OaAppServerModel.php';
require_once OPEN_LIB_PATH . '/open/models/OaCompanyModel.php';
require_once OPEN_LIB_PATH . '/open/models/OaCodeModel.php';
require_once OPEN_LIB_PATH . '/open/business-logic/service/OaServiceSync.php';
require_once 'OaAppServerLogic.php';


class OaSyncInfoLogic extends OaLogic
{
    
    /**
     * 同步公司信息
     * @param int $companyId
     * @param string $op
     * @param int $env
     * @param array $company
     * @return boolean 如果名称重复，设置错误号1
     */
    public static function syncCompanyInfo($companyId, $op, $env, $company = null)
    {
        $logger = self::getLogger();        
        $logger->info("syncCompanyInfo, company-$companyId, op-$op, env-$env");
        $companyModel = new OaCompanyModel($logger);
        $codeModel = new OaCodeModel($logger);
        if (is_null($company)) {
        	$company = $companyModel->getCompany($companyId);
        	if (!is_array($company)) {
        		$logger->err("company not exists: company-$companyId");
        		return false;
        	}
        }
        
        // 同步Code库
        if ($op == 'add') {
            if (!$codeModel->addCompany($companyId, $company['name'], 
            	$company['status'], $company['notes'], array(), $env)) {
            	if ($codeModel->getErrorNo() == 1) {
            		self::setError(1, $codeModel->getErrorMessage());
            	} else {
            		$logger->err("sync to code failed: company-$companyId, op-$op, env-$env");
            	}
            	return false;
            }
        } else if ($op == 'update') {
            if (!$codeModel->modifyCompany($companyId, OaCodeModel::convertFieldNameOfCompany($company), 
                $env)) {
            	if ($codeModel->getErrorNo() == 1) {
            		self::setError(1, $codeModel->getErrorMessage());
            	} else {
            		$logger->err("sync to code failed: company-$companyId, op-$op, env-$env");
            	}
            	return false;
            }
        } else if ($op == 'delete') {
            if (!$codeModel->deleteCompany($companyId, $env)) {
            	$logger->err("sync to code failed: company-$companyId, op-$op, env-$env");
            	return false;
            }
        }
    	
    	// 同步OAS库
    	$params = array(
    		'spId' => $companyId,
    		'spName' => $company['name'],
    		'spAddr' => $company['address'],
    		'email' => $company['email'],
    		'phoneNumber' => $company['phone'],
    		'status' => $company['status'],
    		'beginTime' => $company['contract_begin_time'],
    		'endTime' => $company['contract_end_time'],
    		'createUserId' => $company['creator'],
    		'updateUserId' => $company['creator'],
    		'companyUrl' => $company['homepage'],
    		'spCardNum' => $company['legal_person_cert_no'],
    		'productInfo' => $company['intro'],
    		'notes' => $company['notes'],
    		'zipCode' => $company['zip_code']
    	);
    	$messages = '';
    	if (!OASApi::sp($messages, $params, $op, $env)) {
    	    if ($op == 'add') {
                $codeModel->deleteCompany($companyId, $env);
    	    }
    		$logger->err("sync to oas failed: company-$companyId, op-$op, env-$env, message-$messages");
    		return false;
    	}
    	
    	return true;
    }
    
    /**
     * 同步应用信息
     * @param int $appId
     * @param string $op 操作，add为新增，update为更新，delete为删除
     * @param int $env
     * @param array $app
     * @return boolean 如果名称重复，设置错误号1
     */
    public static function syncAppInfo($appId, $op, $env, $app = null)
    {
        $logger = self::getLogger();
        $logger->info("syncAppInfo, app-$appId, op-$op, env-$env");
        $appModel = new OaAppModel($env, $logger);
        $appServerModel = new OaAppServerModel($env, $logger);
        $codeModel = new OaCodeModel($logger);
        
        if (is_null($app)) {
        	$app = $appModel->getApp($appId);
        	if (!is_array($app)) {
        		$logger->err("app not exists, app-$appId");
        		return false;
        	}
        }
        if (isset($app['status'])) {
            $app['status'] = ($app['status'] == OaAppModel::APP_STATUS_DELETE ? 2 : 1);
        }
    	
        // 同步到Code库
    	if ($op == 'add') {
            if (!$codeModel->addApp($appId, $app['name'], $app['company_id'], 
            	$app['status'], $app['notes'], array(), $env)) {
            	if ($codeModel->getErrorNo() == 1) {
            		self::setError(1, $codeModel->getErrorMessage());
            	} else {
            		$logger->err("sync to code failed: app-$appId, op-$op, env-$env");
            	}
            	return false;
            }
            if (__OA_ENV != "ONLINE" && $app['join_type'] == OaAppModel::APP_JOIN_FLOW_FAST_SINGLE) {
            	$codeModel->addApp($appId, $app['name'], $app['company_id'], 
            	    $app['status'], $app['notes'], array(), OaAppModel::APP_CONFIG_ENV_TEST);
            }
    	} else if ($op == 'update') {
            if (! $codeModel->modifyApp($appId, OaCodeModel::convertFieldNameOfApp($app), 
                $env)) {
            	if ($codeModel->getErrorNo() == 1) {
            		self::setError(1, $codeModel->getErrorMessage());
            	} else {
                	$logger->err("sync to code failed: app-$appId, op-$op, env-$env");
            	}
            	return false;
            }
    	    if (__OA_ENV != "ONLINE" && $app['join_type'] == OaAppModel::APP_JOIN_FLOW_FAST_SINGLE) {
            	$codeModel->modifyApp($appId, OaCodeModel::convertFieldNameOfApp($app), 
            	    OaAppModel::APP_CONFIG_ENV_TEST);
            }
    	} else if ($op == 'delete') {
            if (! $codeModel->deleteApp($appId, $env)) {
                $logger->err("sync to code failed: app-$appId");
            	return false;
            }
    	    if (__OA_ENV != "ONLINE" && $app['join_type'] == OaAppModel::APP_JOIN_FLOW_FAST_SINGLE) {
            	$codeModel->deleteApp($appId, OaAppModel::APP_CONFIG_ENV_TEST);
            }
    	}
    	
        // 同步OA库
        $params = array(
            'appId' => $appId,
            'typeId' => 1,
            'appName' => $app['name'],
            'spId' => $app['company_id'],
            'timeTypeId' => $app['pay_type'],
            'createUser' => $app['creator'],
            'manageId' => $app['type'],
            'auditFlag' => $app['status'],
            'note' => '',
            'signarith' => $app['encrypt_type']
        );
        if (!empty($app['game_currency_name'])) {
        	$params['currencyList'] = array(
                array(
                	'currencyName' => $app['game_currency_name'], 
                	'currencyRate' => $app['game_currency_rate']
                )
            );
        }
        $message = '';
        if (!OAApi::app($message, $params, $op, $env)) {
            $logger->err("sync to oa failed: message-$message, app-$appId");
            if ($op == 'add') {
                $codeModel->deleteApp($appId, $env);
            }
            return false;
        }
        
        // 同步OAS库
        $params = array(
            'appId' => $appId,
            'typeId' => 1,
            'appName' => $app['name'],
            'status' => $app['status'],
            'spId' => $app['company_id'],
            'timeTypeId' => $app['pay_type'],
            'createUser' => $app['creator'],
            'payTypeId' => 3,
            'manageId' => $app['type'],
            'signArith' => $app['encrypt_type']
        );
        $message = '';
        if (!OASApi::app($message, $params, $op, $env)) {
            $logger->err("sync to oas failed: message-$message, app-$appId");
            if ($op == 'add') {
                $codeModel->deleteApp($appId, $env);
                OAApi::app($message, $params, 'delete', $env);
            }
            return false;
        }
        
        if ($op == 'add') {
            // 同步默认区组
            $area = $appServerModel->getAreaByAreaCode($appId, 0, $env);
            if (is_array($area) && !self::syncAreaInfo($area['id'], 'add')) {
                $logger->err("sync 0 area failed: area-{$area['id']}");
                $codeModel->deleteApp($appId, $env);
                OAApi::app($message, $params, 'delete', $env);
                OASApi::app($message, $params, 'delete', $env);
                return false;
            }
            $group = $appServerModel->getGroupByGroupCode($area['id'], 0);
            if (is_array($group) && !self::syncGroupInfo($group['id'], 'add')) {
                $logger->err("sync 0 group failed: group-{$group['id']}");
                $codeModel->deleteApp($appId, $env);
                OAApi::app($message, $params, 'delete', $env);
                OASApi::app($message, $params, 'delete', $env);
                self::syncAreaInfo($area['id'], 'delete');
                return false;
            }
        }
        
        // 更新最后一个订单的快照
//        $appCfgOrdMod = new OaAppConfigOrderModel($logger);
//        $order = $appCfgOrdMod->getAppLastConfigOrder($appId);
//        if (is_array($order)) {
//        	if (!$appCfgOrdMod->updateAppSnapshot($order['id'], $env, 'basic_info')) {
//        		$logger->warning("update snapshot failed: order-{$order['id']}, env-$env, column-basic_info");
//        	}
//        }

        return true;
    }
    
    /**
     * 同步应用公钥
     * @param int $appId
     * @param int $env
     * @return boolean
     */
    public static function syncAppPubKey($appId, $env)
    {
        $logger = self::getLogger();
        $logger->info("syncAppPubKey: app-$appId, env-$env");
        $appModel = new OaAppModel($env, $logger);
        
    	$app = $appModel->getApp($appId);
    	if (!is_array($app)) {
    		$logger->err("app not exists: app=$appId");
    		return false;
    	}
        $message = '';
        if (!OASApi::rsa(&$message, array(
            'spId' => $app['company_id'],
            'appId' => $appId,
        	'appPublicKey' => $app['app_pub_key']
        ), 'update', $env)) {
            $logger->err("sync app pub key failed: message-$message, app-$appId");
            return false;
        }
        
        // 更新最后一个订单的快照
//        $appCfgOrdMod = new OaAppConfigOrderModel($logger);
//        $order = $appCfgOrdMod->getAppLastConfigOrder($appId);
//        if (is_array($order)) {
//        	if (!$appCfgOrdMod->updateAppSnapshot($order['id'], $env, 'basic_info')) {
//        		$logger->warning("update snapshot failed: order-{$order['id']}, env-$env, column-basic_info");
//        	}
//        }
        
        return true;
    }
    
    /**
     * 同步游戏服务器修改
     * @param int $appId
     * @param int $env
     * @return array|boolean 如果成功，返回同步结果，数据结构如下
     * array(	游戏服务器修改，格式说明见OaAppServerLogic::getGSChanges接口
     *   array(						区修改
     *     ...
     *     sync_result => array(	同步结果
     *       errno => ...			错误号，0表示成功，其余表示失败
     *       error => ...			错误信息
     *     ),
     *     group_changes => array(		区下的组修改
     *       ...
     *       sync_result => array(		同步结果
     *         errno => ...				错误号，0表示成功，其余表示失败
     *         error => ...				错误信息
     *       ),
     *       server_changes => array(		组下的服务器修改
     *         ...
     *         sync_result => array(		同步结果
     *           errno => ...				错误号，0表示成功，其余表示失败，其中1表示IP+别名冲突
     *           error => ...				错误信息
     *         )
     *       )
     *     )
     *   ),
     *   ...
     * )
     */
    public static function syncGSChanges($appId, $env)
    {
        $logger = self::getLogger();
        $appServerModel = new OaAppServerModel(OaAppModel::APP_CONFIG_ENV_TEST, $logger);
    	$areaChanges = OaAppServerLogic::getGSChanges($appId, $env);
    	if (!is_array($areaChanges)) {
    		$logger->err("get gs changes failed: app-$appId, env-$env");
    		return false;
    	}
    	foreach ($areaChanges as &$areaChange) {
    		$areaChange['sync_result'] = array('errno' => 0, 'error' => '');
    		if ($areaChange['op'] == 'add') {
    		    $area = $areaChange['new'];
    			$ret = self::syncAreaInfo($area['id'], 'add', $area);
	    		if (!$ret) {
	    			$areaChange['sync_result']['errno'] = -1;
	    			$appServerModel->deleteArea($area['id']);
	    			continue;
	    		}
	    		foreach ($areaChange['group_changes'] as &$groupChange) {
		    		$groupChange['sync_result'] = array('errno' => 0, 'error' => '');
		    		$group = $groupChange['new'];
		    		$ret = self::syncGroupInfo($group['id'], 'add', $group);
	    			if (!$ret) {
	    				$groupChange['sync_result']['errno'] = -1;
	    				$appServerModel->deleteGroup($group['id']);
	    				continue;
	    			}
		    		foreach ($groupChange['server_changes'] as &$serverChange) {
			    		$serverChange['sync_result'] = array('errno' => 0, 'error' => '');
			    		$server = $serverChange['new'];
			    		$ret = self::syncServerInfo($server['id'], 'add', $server);
		    			if (!$ret) {
		    				if (self::getErrorNo() == 1) {
		    					$errno = 1;
		    				} else {
		    					$errno = -1;
		    				}
		    				$serverChange['sync_result']['errno'] = $errno;
		    				$appServerModel->deleteServer($server['id']);
		    			}
		    		}
	    		}
    		} else if ($areaChange['op'] == 'update' || empty($areaChange['op'])) {
    			if ($areaChange['op'] == 'update') {
    		        $area = $areaChange['new'];
	    			$ret = self::syncAreaInfo($area['id'], 'update', $area);
		    		if (!$ret) {
		    			$areaChange['sync_result']['errno'] = -1;
    		            $row = $areaChange['old'];
    		            unset($row['id']);
		    			$appServerModel->modifyArea($areaChange['old']['id'], $row);
		    		}
    			}
	    		foreach ($areaChange['group_changes'] as &$groupChange) {
		    		$groupChange['sync_result'] = array('errno' => 0, 'error' => '');
		    		if ($groupChange['op'] == 'add') {
		    		    $group = $groupChange['new'];
		    			$ret = self::syncGroupInfo($group['id'], 'add', $group);
		    			if (!$ret) {
		    				$groupChange['sync_result']['errno'] = -1;
	    				    $appServerModel->deleteGroup($group['id']);
	    				    continue;
		    			}
			    		foreach ($groupChange['server_changes'] as &$serverChange) {
				    		$serverChange['sync_result'] = array('errno' => 0, 'error' => '');
			    		    $server = $serverChange['new'];
				    		$ret = self::syncServerInfo($server['id'], 'add', $server);
			    			if (!$ret) {
			    				if (self::getErrorNo() == 1) {
			    					$errno = 1;
			    				} else {
			    					$errno = -1;
			    				}
			    				$serverChange['sync_result']['errno'] = $errno;
		    				    $appServerModel->deleteServer($server['id']);
			    			}
			    		}
		    		} else if ($groupChange['op'] == 'update' || empty($groupChange['op'])) {
		    			if ($groupChange['op'] == 'update') {
		    			    $group = $groupChange['new'];
			    			$ret = self::syncGroupInfo($group['id'], 'update', $group);
			    			if (!$ret) {
			    				$groupChange['sync_result']['errno'] = -1;
			    				$row = $groupChange['old'];
			    				unset($row['id']);
			    				$appServerModel->modifyGroup($groupChange['old']['id'], $row);
			    			}
		    			}
			    		foreach ($groupChange['server_changes'] as &$serverChange) {
				    		$serverChange['sync_result'] = array('errno' => 0, 'error' => '');
				    		if ($serverChange['op'] == 'add') {
			    		        $server = $serverChange['new'];
				    			$ret = self::syncServerInfo($server['id'], 'add', $server);
    			    			if (!$ret) {
    			    				if (self::getErrorNo() == 1) {
    			    					$errno = 1;
    			    				} else {
    			    					$errno = -1;
    			    				}
    			    				$serverChange['sync_result']['errno'] = $errno;
		    				        $appServerModel->deleteServer($server['id']);
    			    			}
				    		} else if ($serverChange['op'] == 'update') {
			    		        $server = $serverChange['new'];
			    		        $server['old_ip'] = $serverChange['old']['ip'];
			    		        $server['old_alias'] = $serverChange['old']['alias'];
				    			$ret = self::syncServerInfo($server['id'], 'update', $server);
    			    			if (!$ret) {
    			    				if (self::getErrorNo() == 1) {
    			    					$errno = 1;
    			    				} else {
    			    					$errno = -1;
    			    				}
    			    				$serverChange['sync_result']['errno'] = $errno;
    			    				$row = $serverChange['old'];
    			    				unset($row['id']);
    			    				$appServerModel->modifyServer($serverChange['old']['id'], $row);
    			    			}
				    		} else if ($serverChange['op'] == 'delete') {
			    		        $server = $serverChange['old'];
				    			$ret = self::syncServerInfo($server['id'], 'delete', $server);
    			    			if (!$ret) {
    			    				if (self::getErrorNo() == 1) {
    			    					$errno = 1;
    			    				} else {
    			    					$errno = -1;
    			    				}
    			    				$serverChange['sync_result']['errno'] = $errno;
    			    				$appServerModel->addServer($server['group_id'], 
    			    				    $server['ip'], $server['alias'], $server);
    			    			}
				    		}
			    		}
		    		} else if ($groupChange['op'] == 'delete') {
		    		    $revertServer = false;
			    		foreach ($groupChange['server_changes'] as &$serverChange) {
				    		$serverChange['sync_result'] = array('errno' => 0, 'error' => '');
				    		$server = $serverChange['old'];
				    		$ret = self::syncServerInfo($server['id'], 'delete', $server);
			    			if (!$ret) {
			    				if (self::getErrorNo() == 1) {
			    					$errno = 1;
			    				} else {
			    					$errno = -1;
			    				}
			    				$serverChange['sync_result']['errno'] = $errno;
			    				$appServerModel->addServer($server['group_id'], 
			    				    $server['ip'], $server['alias'], $server);
			    				$revertServer = true;
			    			}
			    		}
			    		$group = $groupChange['old'];
			    		if (!$revertServer) {
		    			    $ret = self::syncGroupInfo($group['id'], 'delete', $group);
			    		} else {
			    		    $ret = false;
			    		}
		    			if (!$ret) {
		    				$groupChange['sync_result']['errno'] = -1;
		    				$appServerModel->addGroup($group['area_id'], $group['name'], 
		    				    $group['idc_type'], $group);
		    			}
		    		}
	    		}
    		} else if ($areaChange['op'] == 'delete') {
	    		$area = $areaChange['old'];
		        $revertGroup = false;
	    		foreach ($areaChange['group_changes'] as &$groupChange) {
		    		$group = $groupChange['old'];
	    		    $revertServer = false;
		    		foreach ($groupChange['server_changes'] as &$serverChange) {
			    		$serverChange['sync_result'] = array('errno' => 0, 'error' => '');
				    	$server = $serverChange['old'];
			    		$ret = self::syncServerInfo($server['id'], 'delete', $server);
		    			if (!$ret) {
		    				if (self::getErrorNo() == 1) {
		    					$errno = 1;
		    				} else {
		    					$errno = -1;
		    				}
		    				$serverChange['sync_result']['errno'] = $errno;
		    				if (!is_array($appServerModel->getArea($group['area_id']))) {
            	    			$appServerModel->addArea($area['app_id'], $area['name'], $area['idc_type'], 
            	    			    $area);
		    				}
		    				if (!is_array($appServerModel->getGroup($server['group_id']))) {
        	    				$appServerModel->addGroup($group['area_id'], $group['name'], 
        	    				    $group['idc_type'], $group);
		    				}
		    				$appServerModel->addServer($server['group_id'], 
		    				    $server['ip'], $server['alias'], $server);
		    				$revertServer = true;
		    			}
		    		}
		    		$groupChange['sync_result'] = array('errno' => 0, 'error' => '');
		    		if (!$revertServer) {
	    			    $ret = self::syncGroupInfo($group['id'], 'delete', $group);
		    		} else {
		    		    $ret = false;
		    		}
	    			if (!$ret) {
	    				$groupChange['sync_result']['errno'] = -1;
	    				$revertGroup = true;
	    			}
	    		}
    		    if (!$revertGroup) {
    			    $ret = self::syncAreaInfo($area['id'], 'delete', $area);
	    		} else {
	    		    $ret = false;
	    		}
	    		if (!$ret) {
	    			$areaChange['sync_result']['errno'] = -1;
	    		}
    		}
    	}
        
        // 更新最后一个订单的快照
        $appCfgOrdMod = new OaAppConfigOrderModel($logger);
        $order = $appCfgOrdMod->getAppLastConfigOrder($appId);
        if (is_array($order)) {
        	if (!$appCfgOrdMod->updateAppSnapshot($order['id'], $env, 'area_info')) {
        		$logger->warning("update snapshot failed: order-{$order['id']}, env-$env, column-area_info");
        	}
        	if (!$appCfgOrdMod->updateAppSnapshot($order['id'], $env, 'group_info')) {
        		$logger->warning("update snapshot failed: order-{$order['id']}, env-$env, column-group_info");
        	}
        	if (!$appCfgOrdMod->updateAppSnapshot($order['id'], $env, 'server_info')) {
        		$logger->warning("update snapshot failed: order-{$order['id']}, env-$env, column-server_info");
        	}
        }
        $logger->info($areaChanges);
    	return $areaChanges;
    }
    
    /**
     * 同步登录服务器修改
     * @param int $appId
     * @param int $env
     * @return array|boolean 如果成功，返回同步结果，数据结构如下
     * array(	登录服务器修改，格式说明见OaAppServerLogic::getLSChanges接口
     *   array(						登录服务器修改
     *     ...
     *     sync_result => array(	同步结果
     *       errno => ...			错误号，0表示成功，其余表示失败，其中1表示IP+别名冲突
     *       error => ...			错误信息
     *     ),
     *     va_changes => array(			生效范围修改
     *       ...
     *       sync_result => array(		同步结果
     *         errno => ...				错误号，0表示成功，其余表示失败
     *         error => ...				错误信息
     *       )
     *     )
     *   ),
     *   ...
     * )
     */
    public static function syncLSChanges($appId, $env)
    {
        $logger = self::getLogger();
        $appServerModel = new OaAppServerModel(OaAppModel::APP_CONFIG_ENV_TEST, $logger);
    	$lsChanges = OaAppServerLogic::getLSChanges($appId, $env);
    	if (!is_array($lsChanges)) {
    		$logger->err("get gs changes failed: app-$appId, env-$env");
    		return false;
    	}
    	foreach ($lsChanges as &$lsChange) {
    		$lsChange['sync_result'] = array('errno' => 0, 'error' => '');
    		if ($lsChange['op'] == 'add') {
    		    $ls = $lsChange['new'];
    			$ret = self::syncLoginServerInfo($ls['id'], 'add', $ls);
	    		if (!$ret) {
	    			if (self::getErrorNo() == 1) {
	    				$errno = 1;
	    			} else {
	    				$errno = -1;
	    			}
	    			$lsChange['sync_result']['errno'] = $errno;
	    			$appServerModel->deleteLoginServer($ls['id']);
	    			continue;
	    		}
	    		foreach ($lsChange['va_changes'] as &$vaChange) {
		    		$vaChange['sync_result'] = array('errno' => 0, 'error' => '');
		    		$va = $vaChange['new'];
		    		$ret = self::syncLoginServerValidToInfo($va['id'], 'add', $va);
	    			if (!$ret) {
	    				$vaChange['sync_result']['errno'] = -1;
	    				$appServerModel->deleteLoginServerValidTo($va['id']);
	    			}
	    		}
    		} else if ($lsChange['op'] == 'update' || empty($lsChange['op'])) {
    			if ($lsChange['op'] == 'update') {
    			    $ls = $lsChange['new'];
    			    $ls['old_ip'] = $lsChange['old']['ip'];
    			    $ls['old_alias'] = $lsChange['old']['alias'];
	    			$ret = self::syncLoginServerInfo($ls['id'], 'update', $ls);
		    		if (!$ret) {
		    			if (self::getErrorNo() == 1) {
		    				$errno = 1;
		    			} else {
		    				$errno = -1;
		    			}
		    			$lsChange['sync_result']['errno'] = $errno;
		    			$row = $lsChange['old'];
		    			unset($row['id']);
		    			$appServerModel->modifyLoginServer($lsChange['old']['id'], $row);
		    		}
    			}
	    		foreach ($lsChange['va_changes'] as &$vaChange) {
		    		$vaChange['sync_result'] = array('errno' => 0, 'error' => '');
		    		if ($vaChange['op'] == 'add') {
		    		    $va = $vaChange['new'];
		    			$ret = self::syncLoginServerValidToInfo($va['id'], 'add', $va);
    	    			if (!$ret) {
    	    				$vaChange['sync_result']['errno'] = -1;
    	    				$appServerModel->deleteLoginServerValidTo($va['id']);
    	    			}
		    		} else if ($vaChange['op'] == 'update') {
		    		    $va = $vaChange['new'];
		    			$ret = self::syncLoginServerValidToInfo($va['id'], 'update', $va);
    	    			if (!$ret) {
    	    				$vaChange['sync_result']['errno'] = -1;
    	    				$row = $vaChange['old'];
    	    				unset($row['id']);
    	    				$appServerModel->modifyLoginServerValidTo($vaChange['old']['id'], $row);
    	    			}
		    		} else if ($vaChange['op'] == 'delete') {
		    		    $va = $vaChange['old'];
		    			$ret = self::syncLoginServerValidToInfo($va['id'], 'delete', $va);
    	    			if (!$ret) {
    	    				$vaChange['sync_result']['errno'] = -1;
    	    				$appServerModel->addLoginServerValidTo($va['login_server_id'], 
    	    				    $va['valid_to_area'], $va['valid_to_group'], $va['valid_to_server'], 
    	    				    $va);
    	    			}
		    		}
	    		}
    		} else if ($lsChange['op'] == 'delete') {
	    		$ls = $lsChange['old'];
    		    $revert = false;
	    		foreach ($lsChange['va_changes'] as &$vaChange) {
		    		$vaChange['sync_result'] = array('errno' => 0, 'error' => '');
		    		$va = $vaChange['old'];
		    		$ret = self::syncLoginServerValidToInfo($va['id'], 'delete', $va);
	    			if (!$ret) {
	    				$vaChange['sync_result']['errno'] = -1;
	    				if (!is_array($appServerModel->getLoginServer($va['login_server_id']))) {
        	    			$appServerModel->addLoginServer($ls['app_id'], $ls['ip'], $ls['alias'], 
        	    			    $ls['idc_type'], $ls);
	    				}
	    				$appServerModel->addLoginServerValidTo($va['login_server_id'], 
	    				    $va['valid_to_area'], $va['valid_to_group'], $va['valid_to_server'], 
	    				    $va);
	    				$revert = true;
	    			}
	    		}
	    		if (!$revert) {
    			    $ret = self::syncLoginServerInfo($ls['id'], 'delete', $ls);
	    		} else {
	    		    $ret = false;
	    		}
	    		if (!$ret) {
	    			if (self::getErrorNo() == 1) {
	    				$errno = 1;
	    			} else {
	    				$errno = -1;
	    			}
	    			$lsChange['sync_result']['errno'] = $errno;
	    		}
    		}
    	}
        
        // 更新最后一个订单的快照
        $appCfgOrdMod = new OaAppConfigOrderModel($logger);
        $order = $appCfgOrdMod->getAppLastConfigOrder($appId);
        if (is_array($order)) {
        	if (!$appCfgOrdMod->updateAppSnapshot($order['id'], $env, 'login_server_info')) {
        		$logger->warning("update snapshot failed: order-{$order['id']}, env-$env, column-login_server_info");
        	}
        	if (!$appCfgOrdMod->updateAppSnapshot($order['id'], $env, 'login_server_valid_info')) {
        		$logger->warning("update snapshot failed: order-{$order['id']}, env-$env, column-login_server_valid_info");
        	}
        }
        $logger->info($lsChanges);
    	return $lsChanges;
    }
    
    /**
     * 同步发货服务器修改
     * @param int $appId
     * @param int $env
     * @return array|boolean 如果成功，返回同步结果，数据结构如下
     * array(	发货服务器修改，格式说明见OaAppServerLogic::getPSChanges接口
     *   array(						发货服务器修改
     *     ...
     *     sync_result => array(	同步结果
     *       errno => ...			错误号，0表示成功，其余表示失败，其中1表示IP+别名冲突
     *       error => ...			错误信息
     *     ),
     *     va_changes => array(			生效范围修改
     *       ...
     *       sync_result => array(		同步结果
     *         errno => ...				错误号，0表示成功，其余表示失败
     *         error => ...				错误信息
     *       )
     *     )
     *   ),
     *   ...
     * )
     */
    public static function syncPSChanges($appId, $env)
    {
        $logger = self::getLogger();
        $appServerModel = new OaAppServerModel(OaAppModel::APP_CONFIG_ENV_TEST, $logger);
    	$psChanges = OaAppServerLogic::getPSChanges($appId, $env);
    	if (!is_array($psChanges)) {
    		$logger->err("get gs changes failed: app-$appId, env-$env");
    		return false;
    	}
    	foreach ($psChanges as &$psChange) {
    		$psChange['sync_result'] = array('errno' => 0, 'error' => '');
    		if ($psChange['op'] == 'add') {
    		    $ps = $psChange['new'];
    			$ret = self::syncPayServerInfo($ps['id'], 'add', $ps);
	    		if (!$ret) {
	    			if (self::getErrorNo() == 1) {
	    				$errno = 1;
	    			} else {
	    				$errno = -1;
	    			}
	    			$psChange['sync_result']['errno'] = $errno;
	    			$appServerModel->deletePayServer($ps['id']);
	    			continue;
	    		}
	    		foreach ($psChange['va_changes'] as &$vaChange) {
		    		$vaChange['sync_result'] = array('errno' => 0, 'error' => '');
		    		$va = $vaChange['new'];
		    		$ret = self::syncPayServerValidToInfo($va['id'], 'add', $va);
	    			if (!$ret) {
	    				$vaChange['sync_result']['errno'] = -1;
	    				$appServerModel->deletePayServerValidTo($va['id']);
	    			}
	    		}
    		} else if ($psChange['op'] == 'update' || empty($psChange['op'])) {
    			if ($psChange['op'] == 'update') {
    			    $ps = $psChange['new'];
    			    $ps['old_ip'] = $psChange['old']['ip'];
    			    $ps['old_alias'] = $psChange['old']['alias'];
	    			$ret = self::syncPayServerInfo($ps['id'], 'update', $ps);
		    		if (!$ret) {
		    			if (self::getErrorNo() == 1) {
		    				$errno = 1;
		    			} else {
		    				$errno = -1;
		    			}
		    			$psChange['sync_result']['errno'] = $errno;
		    			$row = $psChange['old'];
		    			unset($row['id']);
		    			$appServerModel->modifyPayServer($psChange['old']['id'], $row);
		    		}
    			}
	    		foreach ($psChange['va_changes'] as &$vaChange) {
		    		$vaChange['sync_result'] = array('errno' => 0, 'error' => '');
		    		if ($vaChange['op'] == 'add') {
		    		    $va = $vaChange['new'];
		    			$ret = self::syncPayServerValidToInfo($va['id'], 'add', $va);
    	    			if (!$ret) {
    	    				$vaChange['sync_result']['errno'] = -1;
    	    				$appServerModel->deletePayServerValidTo($va['id']);
    	    			}
		    		} else if ($vaChange['op'] == 'update') {
		    		    $va = $vaChange['new'];
		    			$ret = self::syncPayServerValidToInfo($va['id'], 'update', $va);
    	    			if (!$ret) {
    	    				$vaChange['sync_result']['errno'] = -1;
    	    				$row = $vaChange['old'];
    	    				unset($row['id']);
    	    				$appServerModel->modifyPayServerValidTo($vaChange['old']['id'], $row);
    	    			}
		    		} else if ($vaChange['op'] == 'delete') {
		    		    $va = $vaChange['old'];
		    			$ret = self::syncPayServerValidToInfo($va['id'], 'delete', $va);
    	    			if (!$ret) {
    	    				$vaChange['sync_result']['errno'] = -1;
    	    				$appServerModel->addPayServerValidTo($va['pay_server_id'], 
    	    				    $va['valid_to_area'], $va['valid_to_group'], $va['valid_to_server'], 
    	    				    $va);
    	    			}
		    		}
	    		}
    		} else if ($psChange['op'] == 'delete') {
	    		$ps = $psChange['old'];
    		    $revert = false;
	    		foreach ($psChange['va_changes'] as &$vaChange) {
		    		$vaChange['sync_result'] = array('errno' => 0, 'error' => '');
		    		$va = $vaChange['old'];
		    		$ret = self::syncPayServerValidToInfo($va['id'], 'delete', $va);
	    			if (!$ret) {
	    				$vaChange['sync_result']['errno'] = -1;
	    				if (!is_array($appServerModel->getPayServer($va['pay_server_id']))) {
        	    			$appServerModel->addPayServer($ps['app_id'], $ps['type'], $ps['addr'], 
        	    			    $ps['ip'], $ps['alias'], $ps['idc_type'], $ps);
	    				}
	    				$appServerModel->addPayServerValidTo($va['pay_server_id'], 
	    				    $va['valid_to_area'], $va['valid_to_group'], $va['valid_to_server'], 
	    				    $va);
	    				$revert = true;
	    			}
	    		}
	    		if (!$revert) {
    			    $ret = self::syncPayServerInfo($ps['id'], 'delete', $ps);
	    		} else {
	    		    $ret = false;
	    		}
	    		if (!$ret) {
	    			if (self::getErrorNo() == 1) {
	    				$errno = 1;
	    			} else {
	    				$errno = -1;
	    			}
	    			$psChange['sync_result']['errno'] = $errno;
	    		}
    		}
    	}
        
        // 更新最后一个订单的快照
        $appCfgOrdMod = new OaAppConfigOrderModel($logger);
        $order = $appCfgOrdMod->getAppLastConfigOrder($appId);
        if (is_array($order)) {
        	if (!$appCfgOrdMod->updateAppSnapshot($order['id'], $env, 'pay_server_info')) {
        		$logger->warning("update snapshot failed: order-{$order['id']}, env-$env, column-pay_server_info");
        	}
        	if (!$appCfgOrdMod->updateAppSnapshot($order['id'], $env, 'pay_server_valid_info')) {
        		$logger->warning("update snapshot failed: order-{$order['id']}, env-$env, column-pay_server_valid_info");
        	}
        }
        $logger->info($psChanges);
    	return $psChanges;
    }
    
    /**
     * 同步分区信息
     * @param int $areaId
     * @param string $op 操作，add为新增，update为更新，delete为删除
     * @param array $area
     * @return boolean
     */
    public static function syncAreaInfo($areaId, $op, $area = null)
    {
        $logger = self::getLogger();
        $logger->info("syncAreaInfo: area-$areaId, op-$op");
        $appModel = new OaAppModel(OaAppModel::APP_CONFIG_ENV_TEST, $logger);
        $appServerModel = new OaAppServerModel(OaAppModel::APP_CONFIG_ENV_TEST, $logger);
        $codeModel = new OaCodeModel($logger);
        if (is_null($area)) {
        	$area = $appServerModel->getArea($areaId);
        	if (!is_array($area)) {
        		$logger->warning("area not exists: area-$areaId");
        		return false;
        	}
        }
        $appId = (int) $area['app_id'];
        $app = $appModel->getApp($appId);
        if (!is_array($app)) {
        	$logger->warning("app not exists: app-$appId");
        	return false;
        }
        
        // 同步Code库
    	if ($op == 'add') {
            if (!$codeModel->addArea($area['app_id'], $area['area_code'], $area['name'], 
            	$area['status'], '', array(), $area['environment'])) {
            	$logger->warning("sync to code failed: area-$areaId");
    		    return false;
            }
    	    if (__OA_ENV != "ONLINE" && $app['join_type'] == OaAppModel::APP_JOIN_FLOW_FAST_SINGLE) {
            	$codeModel->addArea($area['app_id'], $area['area_code'], $area['name'], 
            	    $area['status'], '', array(), OaAppModel::APP_CONFIG_ENV_TEST);
            }
    	} else if ($op == 'update') {
            if (!$codeModel->modifyArea($area['app_id'], $area['area_code'], 
                OaCodeModel::convertFieldNameOfArea($area), $area['environment'])) {
            	$logger->warning("sync to code failed: area-$areaId");
    		    return false;
            }
    	    if (__OA_ENV != "ONLINE" && $app['join_type'] == OaAppModel::APP_JOIN_FLOW_FAST_SINGLE) {
            	$codeModel->modifyArea($area['app_id'], $area['area_code'], 
                    OaCodeModel::convertFieldNameOfArea($area), OaAppModel::APP_CONFIG_ENV_TEST);
            }
    	} else if ($op == 'delete') {
            if (!$codeModel->deleteArea($app['app_id'], $area['area_code'], 
                $area['environment'])) {
            	$logger->warning("sync to code failed: area-$areaId");
    		    return false;
            }
    	    if (__OA_ENV != "ONLINE" && $app['join_type'] == OaAppModel::APP_JOIN_FLOW_FAST_SINGLE) {
            	$codeModel->deleteArea($area['app_id'], $area['area_code'], 
            	    OaAppModel::APP_CONFIG_ENV_TEST);
            }
    	}
        
    	// 同步OA库
        $params = array(
            'areaId' => $area['area_code'],
            'appId' => $area['app_id'],
            'auditFlag' => 3,
            'createUser' => $area['creator'],
            'name' => $area['name'],
            'status' => $area['status']
        );
        $message = '';
        if (!OAApi::area($message, $params, $op, $area['environment'])) {
            $logger->warning("sync to oa failed: message-$message, area-$areaId");
            if ($op == 'add') {
                $codeModel->deleteArea($area['app_id'], $area['area_code'], $area['environment']);
            }
    		return false;
        }
        
        // 同步OAS库
        $params = array(
            'areaId' => $area['area_code'],
            'appId' => $area['app_id'],
            'name' => $area['name'],
            'status' => $area['status'],
            'regularId' => $area['environment'],
            'createUser' => $area['creator']
        );
        $message = '';
        if (!OASApi::area($message, $params, $op, $area['environment'])) {
            $logger->warning("sync to oas failed: message-$message, area-$areaId");
            if ($op == 'add') {
                $codeModel->deleteArea($area['app_id'], $area['area_code'], $area['environment']);
                OAApi::area($message, $params, 'delete', $area['environment']);
            }
    		return false;
        }
        
    	return true;
    }
    
    /**
     * 同步分组信息
     * @param int $groupId
     * @param string $op 操作，add为新增，update为更新，delete为删除
     * @param array $group
     * @return boolean
     */
    public static function syncGroupInfo($groupId, $op, $group = null)
    {
        $logger = self::getLogger();
        $logger->info("syncGroupInfo: group-$groupId, op-$op");
        $appModel = new OaAppModel(OaAppModel::APP_CONFIG_ENV_TEST, $logger);
        $appServerModel = new OaAppServerModel(OaAppModel::APP_CONFIG_ENV_TEST, $logger);
        $codeModel = new OaCodeModel($logger);
        if (is_null($group)) {
        	$group = $appServerModel->getGroup($groupId);
        	if (!is_array($group)) {
        		$logger->warning("group not exists, group-$groupId");
        		return false;
        	}
        }
        $appId = (int) $group['app_id'];
        $app = $appModel->getApp($appId);
        if (!is_array($app)) {
        	$logger->warning("app not exists: app-$appId");
        	return false;
        }
        
        // 同步Code库
        if ($op == 'add') {
            if (!$codeModel->addGroup($group['app_id'], $group['area_code'], 
                $group['group_code'], $group['name'], $group['status'], '', array(), $group['environment'])) {
            	$logger->warning("sync to code failed, group-$groupId");
    		    return false;
            }
            if (__OA_ENV != "ONLINE" && $app['join_type'] == OaAppModel::APP_JOIN_FLOW_FAST_SINGLE) {
            	$codeModel->addGroup($group['app_id'], $group['area_code'], $group['group_code'], 
            	    $group['name'], $group['status'], '', array(), OaAppModel::APP_CONFIG_ENV_TEST);
            }
        } else if ($op == 'update') {
            if (!$codeModel->modifyGroup($group['app_id'], $group['area_code'], 
                $group['group_code'], OaCodeModel::convertFieldNameOfGroup($group), 
                $group['environment'])) {
            	$logger->warning("sync to code failed, group-$groupId");
    		    return false;
            }
            if (__OA_ENV != "ONLINE" && $app['join_type'] == OaAppModel::APP_JOIN_FLOW_FAST_SINGLE) {
            	$codeModel->modifyGroup($group['app_id'], $group['area_code'], $group['group_code'], 
            	    OaCodeModel::convertFieldNameOfGroup($group), OaAppModel::APP_CONFIG_ENV_TEST);
            }
        } else if ($op == 'delete') {
            if (!$codeModel->deleteGroup($group['app_id'], $group['area_code'], 
                $group['group_code'], $group['environment'])) {
            	$logger->warning("sync to code failed, group-$groupId");
    		    return false;
            }
            if (__OA_ENV != "ONLINE" && $app['join_type'] == OaAppModel::APP_JOIN_FLOW_FAST_SINGLE) {
            	$codeModel->deleteGroup($group['app_id'], $group['area_code'], 
                    $group['group_code'], OaAppModel::APP_CONFIG_ENV_TEST);
            }
        }
    	
        // 同步OA库
        $params = array(
            'groupId' => $group['group_code'],
            'appId' => $group['app_id'],
            'areaId' => $group['area_code'],
            'createUser' => $group['creator'],
            'name' => $group['name'],
            'idc' => $group['idc_type']
        );
        $message = '';
        if (!OAApi::group($message, $params, $op, $group['environment'])) {
            $logger->warning("sync to oa failed, message-$message, group-$groupId");
            if ($op == 'add') {
                $codeModel->deleteGroup($group['app_id'], $group['area_code'], 
                    $group['group_code'], $group['environment']);
            }
    		return false;
        }
        
        // 同步OAS库
        $params = array(
            'groupId' => $group['group_code'],
            'groupName' => $group['name'],
            'areaId' => $group['area_code'],
            'appId' => $group['app_id'],
            'createUser' => $group['creator'],
            'status' => $group['status']
        );
        $message = '';
        if (!OASApi::group($message, $params, $op, $group['environment'])) {
            $logger->warning("sync to oas failed, message-$message, group-$groupId");
            if ($op == 'add') {
                $codeModel->deleteGroup($group['app_id'], $group['area_code'], 
                    $group['group_code'], $group['environment']);
                OAApi::group($message, $params, 'delete', $group['environment']);
            }
    		return false;
        }
        
        return true;
    }
    
    /**
     * 同步服务器信息
     * @param int $serverId
     * @param string $op 操作，add为新增，update为更新，delete为删除
     * @param array $server
     * @return boolean 如果IP+别名重复，设置错误号1
     */
    public static function syncServerInfo($serverId, $op, $server = null)
    {
        $logger = self::getLogger();
        $logger->info("syncServerInfo: server-$serverId, op-$op");
        $appServerModel = new OaAppServerModel(OaAppModel::APP_CONFIG_ENV_TEST, $logger);
        if (is_null($server)) {
        	$server = $appServerModel->getServer($serverId);
        	if (!is_array($server)) {
        		$logger->warning("server not exists, server-$serverId");
        		return false;
        	}
        }
        
        // 同步OAS库
        if ($op == 'add') {
            if (!self::_addIp($server, OaAppServerModel::APP_SERVER_TYPE_GAME)) {
            	if (self::getErrorNo() == 1) {
            		self::setError(1, self::getErrorMessage());
            	} else {
                	$logger->warning("add ip failed");
            	}
                return false;
            }
        } else if ($op == 'update') {
            if (!isset($server['old_ip'])) {
            	$server['old_ip'] = $server['ip'];
            }
            if (!isset($server['old_alias'])) {
            	$server['old_alias'] = $server['alias'];
            }
            if ($server['old_ip'] != $server['ip'] || $server['old_alias'] != $server['alias']) {
                $ip = $server['ip'];
                $alias = $server['alias'];                
                $server['ip'] = $server['old_ip'];
                $server['alias'] = $server['old_alias'];
                if (!self::_deleteIp($server, OaAppServerModel::APP_SERVER_TYPE_GAME)) {
                    $logger->warning("delete ip failed");
                    return false;
                }
                $server['ip'] = $ip;
                $server['alias'] = $alias;
                if (!self::_addIp($server, OaAppServerModel::APP_SERVER_TYPE_GAME)) {
                    $logger->warning("add ip failed");
                    return false;
                }
                $validRows = $appServerModel->getLoginServerValidToByAGS($server['area_id'], 
                    $server['group_id'], $server['id']);
                foreach ($validRows as $validRow) {                        
                    self::syncLoginServerValidToInfo($validRow['id'], 'update');
                }
                $validRows = $appServerModel->getPayServerValidToByAGS($server['area_id'], 
                    $server['group_id'], $server['id']);
                foreach ($validRows as $validRow) {
                    self::syncPayServerValidToInfo($validRow['id'], 'update');
                }
            } else {
                if (!self::_updateIp($server, OaAppServerModel::APP_SERVER_TYPE_GAME)) {
                    $logger->warning("update ip failed");
                    return false;
                }
            }
        } else if ($op == 'delete') {
            if (!self::_deleteIp($server, OaAppServerModel::APP_SERVER_TYPE_GAME)) {
                $logger->warning("delete ip failed");
                return false;
            }
        } else {
            $logger->warning("unknown op: op-$op");
            return false;
        }
        
        return true;
    }
    
    /**
     * 同步登录服务器信息
     * @param int $loginServerId
     * @param string $op 操作，add为新增，update为更新，delete为删除
     * @param array $loginServer
     * @return boolean
     */
    public static function syncLoginServerInfo($loginServerId, $op, $loginServer = null)
    {
        $logger = self::getLogger();
        $logger->info("syncLoginServerInfo, login_server-$loginServerId, op-$op");
        $appServerModel = new OaAppServerModel(OaAppModel::APP_CONFIG_ENV_TEST, $logger);
        if (is_null($loginServer)) {
        	$loginServer = $appServerModel->getLoginServer($loginServerId);
        	if (!is_array($loginServer)) {
        		$logger->warning("login server not exists, login_server-$loginServerId");
        		return false;
        	}        	
        }
        
        // 同步OAS库
        if ($op == 'add') {
            if (!self::_addIp($loginServer, OaAppServerModel::APP_SERVER_TYPE_LOGIN)) {
                $logger->warning("add ip failed");
                return false;
            }
        } else if ($op == 'update') {
            if (!isset($loginServer['old_ip'])) {
            	$loginServer['old_ip'] = $loginServer['ip'];
            }
            if (!isset($loginServer['old_alias'])) {
            	$loginServer['old_alias'] = $loginServer['alias'];
            }
            if ($loginServer['old_ip'] != $loginServer['ip'] || $loginServer['old_alias'] != $loginServer['alias']) {
                $ip = $loginServer['ip'];
                $alias = $loginServer['alias'];                
                $loginServer['ip'] = $loginServer['old_ip'];
                $loginServer['alias'] = $loginServer['old_alias'];
                if (!self::_deleteIp($loginServer, OaAppServerModel::APP_SERVER_TYPE_LOGIN)) {
                    $logger->warning("delete ip failed");
                    return false;
                }
                $loginServer['ip'] = $ip;
                $loginServer['alias'] = $alias;
                if (!self::_addIp($loginServer, OaAppServerModel::APP_SERVER_TYPE_LOGIN)) {
                    $logger->warning("add ip failed");
                    return false;
                }
            } else {
                if (!self::_updateIp($loginServer, OaAppServerModel::APP_SERVER_TYPE_LOGIN)) {
                    $logger->warning("update ip failed");
                    return false;
                }
            }
            $validRows = $appServerModel->getLoginServerValidTo($loginServer['id']);
            foreach ($validRows as $validRow) {                        
                self::syncLoginServerValidToInfo($validRow['id'], 'update');
            }
        } else if ($op == 'delete') {
            if (!self::_deleteIp($loginServer, OaAppServerModel::APP_SERVER_TYPE_LOGIN)) {
                $logger->warning("delete ip failed");
                return false;
            }
        } else {
            $logger->warning("unknown op: op-$op");
            return false;
        }
    	/*授予5种权限*/
        if ($op!="delete") {
            $message = "";
            $params = array('clientIp' => $loginServer['ip'], 'alias' => $loginServer['alias']);
        	$ipInfo = OASApi::ip($message, $params, 'select', $loginServer['environment']);
        	if ($ipInfo && !OASApi::area($message, $ipInfo, 'rightInitial', $loginServer['environment'])) {
        		$logger->log("area rightInitial failure: ip-".$loginServer['ip'].", alias-".$loginServer['alias'].", login_server-$loginServerId");
        	}
        }
        return true;
    }
    
    /**
     * 同步登录服务器生效范围
     * @param int $validToId
     * @param string $op 操作，add为新增，update为更新，delete为删除
     * @param array $validRow
     * @return boolean
     */
    public static function syncLoginServerValidToInfo($validToId, $op, $validRow = null)
    {
        $logger = self::getLogger();
        $logger->info("syncLoginServerValidToInfo, valid_row-$validToId, op-$op");
        $appModel = new OaAppModel(OaAppModel::APP_CONFIG_ENV_TEST, $logger);
        $appServerModel = new OaAppServerModel(OaAppModel::APP_CONFIG_ENV_TEST, $logger);
        if (is_null($validRow) || $op!='delete') {
        	$validRow = $appServerModel->getLoginServerValidToById($validToId);
        	if (!is_array($validRow)) {
        		$logger->warning("valid row not exists, valid_row-$validToId");
        		return false;
        	}
        }
    	$validAreaCode = is_null($validRow['area_code']) ? -1 : $validRow['area_code'];
    	$validGroupCode = is_null($validRow['group_code']) ? -1 : $validRow['group_code'];
    	$validServerIpId = is_null($validRow['server_ip_id']) ? -1 : $validRow['server_ip_id'];
    	$appId = $validRow['app_id'];
    	$app = $appModel->getApp($appId);
    	if (!is_array($app)) {
    		$logger->warning("app not exists: app-$appId");
    		return false;
    	}
        
        // 同步OA库
        $message = '';
        $params = array(
            'spId' => $app['company_id'],
            'groupId' => $validGroupCode,
            'gsipid' => $validServerIpId,
            'loginServerIpid' => $validRow['ip_id'],
            'appId' => $validRow['app_id'],
            'areaId' => $validAreaCode,
            'status' => $validRow['status'],
            'id' => $validRow['login_id'],
            'certifyflag' => 1
        );
        $app = $appModel->getApp($validRow['app_id']);
        if ($app && $app['need_trust_ip'] == OaAppModel::APP_NEED_TRUST_IP && 
            $validRow['environment'] == OaAppModel::APP_CONFIG_ENV_PRODUCTION) {
            if ($op == 'add' || $op == 'update') {
                $oaServiceSync = new OaServiceSync();
        	    if (!$oaServiceSync->addTrustIp($validRow['app_id'], $validAreaCode, 
        	        $validGroupCode, $validRow['ip'], $validRow['environment'], true)) {
                	$logger->warning("add trust ip failed: app-{$validRow['app_id']}, ip-{$validRow['ip']}");
                }
        	    $params['certifyflag'] = 2;
            }
        }
        $loginId = OAApi::login($message, $params, $op, $validRow['environment']);
        if ($loginId === false) {
            $logger->warning("sync to oa login valid failed: valid_row-$validToId, message-$message");
            return false;
        }
        if ($op == 'add') {
            if (!$appServerModel->modifyLoginServerValidTo($validToId, array(
            	'login_id' => $loginId
            ))) {
                $logger->warning("update failed: id-$validToId, login_id-$loginId");
                return false;
            }
        }
        
        return true;
    }
    
    /**
     * 同步充值服务器信息
     * @param int $payServerId
     * @param string $op 操作，add为新增，update为更新，delete为删除
     * @param array $payServer
     * @return boolean
     */
    public static function syncPayServerInfo($payServerId, $op, $payServer = null)
    {
        $logger = self::getLogger();
        $logger->info("syncPayServerInfo, pay_server-$payServerId, op-$op");
        $appServerModel = new OaAppServerModel(OaAppModel::APP_CONFIG_ENV_TEST, $logger);
        if (is_null($payServer)) {
            $payServer = $appServerModel->getPayServer($payServerId);
        	if (!is_array($payServer)) {
        		$logger->warning("pay server not exists, pay_server-$payServerId");
        		return false;
        	}
        }
        if (!isset($payServer['old_ip'])) {
        	$payServer['old_ip'] = $payServer['ip'];
        }
        if (!isset($payServer['old_alias'])) {
        	$payServer['old_alias'] = $payServer['alias'];
        }
        
        // 同步OAS库
        if ($op == 'add') {
            if (!self::_addIp($payServer, OaAppServerModel::APP_SERVER_TYPE_PAY)) {
                $logger->warning("add ip failed");
                return false;
            }
        } else if ($op == 'update') {
            if (!isset($payServer['old_ip'])) {
            	$payServer['old_ip'] = $payServer['ip'];
            }
            if (!isset($payServer['old_alias'])) {
            	$payServer['old_alias'] = $payServer['alias'];
            }
            if ($payServer['old_ip'] != $payServer['ip'] || $payServer['old_alias'] != $payServer['alias']) {
                $ip = $payServer['ip'];
                $alias = $payServer['alias'];                
                $payServer['ip'] = $payServer['old_ip'];
                $payServer['alias'] = $payServer['old_alias'];
                if (!self::_deleteIp($payServer, OaAppServerModel::APP_SERVER_TYPE_PAY)) {
                    $logger->warning("delete ip failed");
                    return false;
                }
                $payServer['ip'] = $ip;
                $payServer['alias'] = $alias;
                if (!self::_addIp($payServer, OaAppServerModel::APP_SERVER_TYPE_PAY)) {
                    $logger->warning("add ip failed");
                    return false;
                }
            } else {
                if (!self::_updateIp($payServer, OaAppServerModel::APP_SERVER_TYPE_PAY)) {
                    $logger->warning("update ip failed");
                    return false;
                }
            }
            $validRows = $appServerModel->getPayServerValidTo($payServer['id']);
            foreach ($validRows as $validRow) {                        
                self::syncPayServerValidToInfo($validRow['id'], 'update');
            }
        } else if ($op == 'delete') {
            if (!self::_deleteIp($payServer, OaAppServerModel::APP_SERVER_TYPE_PAY)) {
                $logger->warning("delete ip failed");
                return false;
            }
        } else {
            $logger->warning("unknown op: op-$op");
            return false;
        }
        //rsa加密方式回滚
        if ($op!="delete") {
        	$message = "";
            $params = array('clientIp' => $payServer['ip'], 'alias' => $payServer['alias']);
            $ipInfo = OASApi::ip($message, $params, 'select', $payServer['environment']);
            $appModel = new OaAppModel($payServer['environment'], $logger);
            $appInfo = $appModel->getApp($ipInfo['appId'], array("encrypt_type"));
            $ipInfo['signArith'] = $appInfo['encrypt_type'];
    	    if (!OASApi::signArith($message, $ipInfo, 'add', $payServer['environment']) && !OASApi::signArith($message, $ipInfo, 'update', $payServer['environment'])) {
    	    	$logger->warning("syncIpSignArith failed: appId-{$ipInfo['appId']}, ip_id-{$ipInfo['ipId']}");
    	    }
    	    unset($appModel);
        }
        return true;
    }
    
    /**
     * 同步充值服务器生效范围
     * @param int $validToId
     * @param string $op 操作，add为新增，update为更新，delete为删除
     * @param array $validRow
     * @param array $tmpQftIds
     * @return boolean
     */
    public static function syncPayServerValidToInfo($validToId, $op, $validRow = null)
    {
        $logger = self::getLogger();
        $logger->info("syncPayServerValidToInfo, valid_row-$validToId, op-$op");
        $appModel = new OaAppModel(OaAppModel::APP_CONFIG_ENV_TEST, $logger);
        $appServerModel = new OaAppServerModel(OaAppModel::APP_CONFIG_ENV_TEST, $logger);
        if (is_null($validRow) || $op!='delete') {
        	$validRow = $appServerModel->getPayServerValidToById($validToId);
        	if (!is_array($validRow)) {
        		$logger->warning("valid row not exists, valid_row-$validToId");
        		return false;
        	}
        }
    	$validAreaCode = is_null($validRow['area_code']) ? -1 : $validRow['area_code'];
    	$validGroupCode = is_null($validRow['group_code']) ? -1 : $validRow['group_code'];
    	$validServerIpId = is_null($validRow['server_ip_id']) ? -1 : $validRow['server_ip_id'];
    	$appId = $validRow['app_id'];
    	$app = $appModel->getApp($appId);
    	if (!is_array($app)) {
    		$logger->warning("app not exists: app-$appId");
    		return false;
    	}
    	
        // 同步OA库
        $params = array(
            'spId' => $app['company_id'],
            'groupId' => $validGroupCode,
            'useridtype' => $validRow['user_id_type'],
            'qftCfgLegacyId' => $validRow['qft_id'],
            'gsipid' => $validServerIpId,
            'ipid' => $validRow['ip_id'],
            'appId' => $validRow['app_id'],
            'areaId' => $validAreaCode,
            'name' => $validRow['alias'],
            'idc' => $validRow['idc_type'],
            'sendaddrtype' => $validRow['type'],
            'sendaddr' => $validRow['addr'],
            'needconfirm' => $validRow['need_confirm'],
            'status' => $validRow['status'],
            'typeid' => $app['pay_type']
        );       
        $message = '';
        $qftId = OAApi::qft($message, $params, $op, $validRow['environment']);
        if ($qftId === false) {
            $logger->warning("sync to oa failed: valid_row-$validToId, message-$message");
            return false;
        }
        if ($op == 'add') {
            if (!$appServerModel->modifyPayServerValidTo($validToId, array(
            	'qft_id' => $qftId
            ))) {
                $logger->warning("update failed: id-$validToId, qft_id-$qftId");
                return false;
            }
        }
        
        return true;
    }
    
    public static function syncIpSignArithBatch($appId, $orgSA, $signArith, $env)
    {
        $logger = self::getLogger();
        $logger->info("syncIpSignArithBatch, appId-{$appId}, org-{$orgSA}, new-{$signArith}");        
        if ($orgSA==$signArith) {
        	return true;
        }
        $appServerModel = new OaAppServerModel($env, $logger);
        $ipList = $appServerModel->getAppPayServers($appId);
        if ($ipList) {
            $params = array('clientIp' => '', 'alias' => '');
            $message = '';                           
        	foreach($ipList as $row) {
        	    $params['clientIp'] = $row['ip'];
        	    $params['alias'] = $row['alias'];
        	    $ipInfo = OASApi::ip($message, $params, 'select', $env);
        	    if (!$ipInfo) {
        	    	continue;
        	    }
        	    $ipInfo['signArith'] = $signArith;
        	    if (!OASApi::signArith($message, $ipInfo, 'add', $env) && !OASApi::signArith($message, $ipInfo, 'update', $env)) {
        	    	$logger->err("syncIpSignArith failed: appId-{$appId}, ip_id-{$ipInfo['ipId']}");
        	    }
        	}
        }
        return true;
    }
    
    private static function _addIp($server, $type)
    {
        $logger = self::getLogger();
        $appServerModel = new OaAppServerModel(OaAppModel::APP_CONFIG_ENV_TEST, $logger);
        $clientProtNum = -1;
        if (isset($server['addr']) && isset($server['type']) && $server['type']==OaAppServerModel::PAY_SERVER_TYPE_SOCKET) {
        	$addr = explode(":", $server['addr']);
        	if ($addr && $addr[1]) {
        		$clientProtNum = $addr[1];
        	}
        }
        $message = '';
        $params = array(
            'appId' => $server['app_id'],
            'areaId' => isset($server['area_code']) ? $server['area_code'] : 0,
            'groupId' => isset($server['group_code']) ? $server['group_code'] : 0,
            'clientIp' => $server['ip'],
            'clientPortNum' => $clientProtNum,
            'clientType' => 1,
            'status' => 1,
            'hostId' => $server['idc_type'],
            'alias' => $server['alias']
        );
        $ipInfo = OASApi::ip($message, $params, 'select', $server['environment']);
        if ($ipInfo) {
            $ipId = $ipInfo['ipId'];
        	$params['ipId'] = $ipId;
            if ($type == OaAppServerModel::APP_SERVER_TYPE_GAME) {
                if ($ipInfo['appId'] != $server['app_id'] || $ipInfo['areaId'] != 0 || 
                    $ipInfo['groupId'] != 0) {
                    self::setError(1, "ip alias duplicated");
                    return false;
                }
    		    if (!OASApi::changeGroup($message, $params, $server['environment'])) {
    		        $logger->warning("OASApi::changeGroup failed: area_id-{$params['areaId']}, " . 
    		        	"group_id-{$params['groupId']}, ip_id-{$params['ipId']}");
    		    	return false;
    		    }
            } else if ($type == OaAppServerModel::APP_SERVER_TYPE_LOGIN || 
                $type == OaAppServerModel::APP_SERVER_TYPE_PAY) {
                if ($ipInfo['appId'] != $server['app_id']) {
                    self::setError(1, "ip alias duplicated");
                    return false;
                }
            }
            // 防止出现无效IP
        	$ipInfo = OASApi::ip($message, $params, 'select', $server['environment']);
        	$params = array_merge($params, $ipInfo);
            if (OASApi::ip($message, $params, 'update', $server['environment']) === false) {
                $logger->warning("OASApi::ip failed: op-update, message-$message, " . 
                	"ip-{$server['ip']}, alias-{$server['alias']}");
                return false;
            }
            $params['ipid'] = $ipId;
            if (!OAApi::ip($message, $params, 'update', $server['environment'])) {
            	$logger->warning("OAApi::ip failed: op-update, message-$message, " . 
                	"ip_id-$ipId, ip-{$server['ip']}, alias-{$server['alias']}");
            }
        } else {
            $ipId = OASApi::ip($message, $params, 'add', $server['environment']);
            if ($ipId === false) {
                $logger->warning("OASApi::ip failed: op-add, message-$message, " . 
                	"ip-{$server['ip']}, alias-{$server['alias']}");
                return false;
            }
            $params['ipid'] = $ipId;
            if (!OAApi::ip($message, $params, 'add', $server['environment'])) {
            	$logger->warning("OAApi::ip failed: op-add, message-$message, " . 
                	"ip_id-$ipId, ip-{$server['ip']}, alias-{$server['alias']}");
            }
        }
        if ($type == OaAppServerModel::APP_SERVER_TYPE_GAME) {
            if (!$appServerModel->modifyServer($server['id'], array(
		    	    'ip_id' => $ipId
		    	))) {
            	$logger->warning("modify server failed: server-{$server['id']}, ip_id-$ipId");
            	return false;
            }
        } else if ($type == OaAppServerModel::APP_SERVER_TYPE_LOGIN) {
            if (!$appServerModel->modifyLoginServer($server['id'], array(
		    	    'ip_id' => $ipId
		    	))) {
            	$logger->warning("modify login server failed: server-{$server['id']}, ip_id-$ipId");
            	return false;
            }
        } else if ($type == OaAppServerModel::APP_SERVER_TYPE_PAY) {
            if (!$appServerModel->modifyPayServer($server['id'], array(
		    	    'ip_id' => $ipId
		    	))) {
            	$logger->warning("modify pay server failed: server-{$server['id']}, ip_id-$ipId");
            	return false;
            }
        }
        return true;
    }
    
    private static function _updateIp($server, $type)
    {
        $logger = self::getLogger();
        $appServerModel = new OaAppServerModel(OaAppModel::APP_CONFIG_ENV_TEST, $logger);
    	$clientProtNum = -1;
        if (isset($server['addr']) && isset($server['type']) && $server['type']==OaAppServerModel::PAY_SERVER_TYPE_SOCKET) {
        	$addr = explode(":", $server['addr']);
        	if ($addr && $addr[1]) {
        		$clientProtNum = $addr[1];
        	}        	
        }
        $message = '';
        $params = array(
            'appId' => $server['app_id'],
            'areaId' => isset($server['area_code']) ? $server['area_code'] : 0,
            'groupId' => isset($server['group_code']) ? $server['group_code'] : 0,
            'clientIp' => $server['ip'],
            'clientPortNum' => $clientProtNum,
            'clientType' => 1,
            'status' => 1,
            'hostId' => $server['idc_type'],
            'alias' => $server['alias']
        );
        if ($type == OaAppServerModel::APP_SERVER_TYPE_LOGIN || $type == OaAppServerModel::APP_SERVER_TYPE_PAY) {
            $gameServer = $appServerModel->getServerByIpAlias($server['ip'], $server['alias'], 
            	$server['environment']);
            if ($gameServer) {
                $params['areaId'] = $gameServer['area_code'];
                $params['groupId'] = $gameServer['group_code'];
            }
        }
        if (!OASApi::ip($message, $params, 'update', $server['environment'])) {
            $logger->warning("OASApi::ip failed: op-update, message-$message, " . 
            	"ip-{$server['ip']}, alias-{$server['alias']}");
            return false;
        }
        $params['ipid'] = $server['ip_id'];
        if (!OAApi::ip($message, $params, 'update', $server['environment'])) {
        	$logger->warning("OAApi::ip failed: op-update, message-$message, " . 
            	"ip_id-{$server['ip_id']}, ip-{$server['ip']}, alias-{$server['alias']}");
        }
        
        return true;
    }
    
    private static function _deleteIp($server, $type)
    {
        $logger = self::getLogger();
        $appServerModel = new OaAppServerModel(OaAppModel::APP_CONFIG_ENV_TEST, $logger);
        $message = '';
        $params = array(
            'appId' => $server['app_id'],
            'areaId' => isset($server['area_code']) ? $server['area_code'] : 0,
            'groupId' => isset($server['group_code']) ? $server['group_code'] : 0,
            'clientIp' => $server['ip'],
            'clientPortNum' => -1,
            'clientType' => 1,
            'status' => 1,
            'hostId' => $server['idc_type'],
            'alias' => $server['alias']
        );
        if ($type == OaAppServerModel::APP_SERVER_TYPE_GAME) {
            if (is_array($appServerModel->getLoginServerByIpAlias($server['ip'], $server['alias'], $server['environment'])) || 
                is_array($appServerModel->getPayServerByIpAlias($server['ip'], $server['alias'], $server['environment']))) {
                $params['areaId'] = 0;
                $params['groupId'] = 0;
                $params['ipId'] = $server['ip_id'];
    		    if (!OASApi::changeGroup($message, $params, $server['environment'])) {
    		        $logger->warning("OASApi::changeGroup failed: area_id-{$params['areaId']}, " . 
    		        	"group_id-{$params['groupId']}, ip_id-{$params['ipId']}");
    		    	return false;
    		    }
            } else {
                if (!OASApi::ip($message, $params, 'delete', $server['environment'])) {
                    $logger->warning("OASApi::ip failed: op-delete, message-$message, " . 
                    	"ip-{$server['ip']}, alias-{$server['alias']}");
                    return false;
                }
                $params['ipid'] = $server['ip_id'];
                if (!OAApi::ip($message, $params, 'delete', $server['environment'])) {
                	$logger->warning("OAApi::ip failed: op-delete, message-$message, " . 
                    	"ip_id-{$server['ip_id']}, ip-{$server['ip']}, alias-{$server['alias']}");
                }
            }
        } else if ($type == OaAppServerModel::APP_SERVER_TYPE_LOGIN) {
            if (is_null($appServerModel->getServerByIpAlias($server['ip'], $server['alias'], $server['environment'])) && 
                is_null($appServerModel->getPayServerByIpAlias($server['ip'], $server['alias'], $server['environment']))) {
                if (!OASApi::ip($message, $params, 'delete', $server['environment'])) {
                    $logger->warning("OASApi::ip failed: op-delete, message-$message, " . 
                    	"ip-{$server['ip']}, alias-{$server['alias']}");
                    return false;
                }
                $params['ipid'] = $server['ip_id'];
                if (!OAApi::ip($message, $params, 'delete', $server['environment'])) {
                	$logger->warning("OAApi::ip failed: op-delete, message-$message, " . 
                    	"ip_id-{$server['ip_id']}, ip-{$server['ip']}, alias-{$server['alias']}");
                }
            }
        } else if ($type == OaAppServerModel::APP_SERVER_TYPE_PAY) {
            if (is_null($appServerModel->getServerByIpAlias($server['ip'], $server['alias'], $server['environment'])) && 
                is_null($appServerModel->getLoginServerByIpAlias($server['ip'], $server['alias'], $server['environment']))) {
                if (!OASApi::ip($message, $params, 'delete', $server['environment'])) {
                    $logger->warning("OASApi::ip failed: op-delete, message-$message, " . 
                    	"ip-{$server['ip']}, alias-{$server['alias']}");
                    return false;
                }
                $params['ipid'] = $server['ip_id'];
                if (!OAApi::ip($message, $params, 'delete', $server['environment'])) {
                	$logger->warning("OAApi::ip failed: op-delete, message-$message, " . 
                    	"ip_id-{$server['ip_id']}, ip-{$server['ip']}, alias-{$server['alias']}");
                }
            }
        }
        return true;
    }
}
